<script lang="ts">
  import { House, Maximize, Minus, Settings, X } from "lucide-svelte";
  import { getCurrentWindow } from "@tauri-apps/api/window";
  import { AppBar, Modal, Progress } from "@skeletonlabs/skeleton-svelte";
  import { appStore } from "$lib/stores/app.svelte";
  import { emit } from "@tauri-apps/api/event";
  import type { AllNotice } from "$lib/api/notice_type";
  import { page } from "$app/state";
  import {
    APP_BOARD_PATH_PREFIX,
    APP_PATH,
  } from "$lib/utils/consts";
  import { goto } from "$app/navigation";
  import { check, Update } from "@tauri-apps/plugin-updater";
  import { exit, relaunch } from "@tauri-apps/plugin-process";
  import { boardStore } from "$lib/stores/board.svelte";

  let theme = $state("");

  const darkMode = (() => {
    if (
      typeof localStorage !== "undefined" &&
      localStorage.getItem("darkMode")
    ) {
      return localStorage.getItem("darkMode");
    }
    if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
      return "dark";
    }
    return "light";
  })();

  if (darkMode === "light") {
    document.documentElement.classList.remove("dark");
  } else {
    document.documentElement.classList.add("dark");
  }

  window.localStorage.setItem("darkMode", darkMode ?? "");
  appStore.darkMode = darkMode == "dark";

  function sendThemeChangeNotice() {
    const notice: AllNotice = {
      ClientNotice: {
        ThemeChangeNotice: {},
      },
    };
    emit("notice", notice);
  }

  const curTheme = (() => {
    if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
      return localStorage.getItem("theme");
    }
    return "cerberus";
  })();

  theme = curTheme ?? "cerberus";

  let updateInfo = $state(null as null | Update);
  let showUpdateModal = $state(false);
  let downloadSize = $state(0);
  let totalSize = $state(1);

  let showCloseModal = $state(false);

  async function checkUpdate() {
    try {
      const tmpUpdate = await check();
      updateInfo = tmpUpdate;
    } catch (e) {
      console.log(e);
    }
  }

  checkUpdate();

  async function runUpdate() {
    if (updateInfo == null) {
      return;
    }
    showUpdateModal = false;
    downloadSize = 0;
    totalSize = 1;
    await updateInfo.downloadAndInstall((ev) => {
      if (ev.event == "Started") {
        totalSize = ev.data.contentLength ?? 1;
      } else if (ev.event == "Progress") {
        downloadSize += ev.data.chunkLength;
      }
    });
    updateInfo = null;
    await relaunch();
  }

  $effect(() => {
    if (theme != "") {
      document.documentElement.setAttribute("data-theme", theme);
      localStorage.setItem("theme", theme);
      sendThemeChangeNotice();
    }
  });
</script>

<AppBar
  padding="p-0"
  trailPadding="p-[10px]"
  trailSpaceX="gap-0"
  background="bg-surface-300-700"
  classes="h-[50px]"
>
  {#snippet lead()}
    <div class="p-[10px] flex items-center gap-2">
      {#if page.url.pathname.startsWith(APP_PATH)}
        <button
          type="button"
          class="btn p-1 hover:preset-filled-primary-900-100"
          onclick={() => {
            goto(APP_PATH);
          }}
        >
          <House />
        </button>
        {#if page.url.pathname.startsWith(APP_BOARD_PATH_PREFIX)}
          <span>/</span>
          {boardStore.curWebBoard?.boardInfo?.basic_info.board_name ?? ""}
        {/if}
      {/if}
    </div>
  {/snippet}
  {#snippet trail()}
    {#if updateInfo != null}
      {#if downloadSize == 0}
        <button
          class="btn-sm text-secondary-800-200 p-2 mr-2"
          onclick={() => (showUpdateModal = true)}
        >
          有新版本
        </button>
      {:else}
        <Progress
          value={downloadSize}
          max={totalSize}
          width="w-[60px]"
          meterBg="bg-primary-900-100"
          trackBg="bg-surface-100-900"
          base="mt-[10px] mr-[10px]"
        ></Progress>
      {/if}
    {/if}

    <select class="select w-[120px] mr-4 h-[24px] pt-0 pb-0" bind:value={theme}>
      <option value="catppuccin">catppuccin</option>
      <option value="cerberus">cerberus</option>
      <option value="concord">concord</option>
      <option value="crimson">crimson</option>
      <option value="hamlindigo">hamlindigo</option>
      <option value="legacy">legacy</option>
      <option value="mint">mint</option>
      <option value="modern">modern</option>
      <option value="mona">mona</option>
      <option value="nouveau">nouveau</option>
      <option value="pine">pine</option>
      <option value="rocket">rocket</option>
      <option value="sahara">sahara</option>
      <option value="seafoam">seafoam</option>
      <option value="terminus">terminus</option>
      <option value="vintage">vintage</option>
      <option value="vox">vox</option>
      <option value="wintry">wintry</option>
    </select>
    {#if page.url.pathname.startsWith(APP_PATH)}
      <button
        type="button"
        class="btn btn-sm hover:preset-tonal p-2 mr-2"
        onclick={() => (appStore.showConfigModal = true)}
      >
        <Settings size={16} />
      </button>
    {/if}
    <button
      type="button"
      class="btn btn-sm hover:preset-tonal p-2"
      onclick={() => getCurrentWindow().minimize()}
    >
      <Minus size={16} />
    </button>
    <button
      type="button"
      class="btn btn-sm hover:preset-tonal p-2"
      onclick={() => getCurrentWindow().toggleMaximize()}
    >
      <Maximize size={16} />
    </button>
    <button
      type="button"
      class="btn btn-sm hover:preset-tonal p-2"
      onclick={() => (showCloseModal = true)}
    >
      <X size={16} />
    </button>
  {/snippet}
  <div data-tauri-drag-region class="cursor-grab h-[50px] w-full"></div>
</AppBar>

<div class="absolute -left-[10000px]">
  {#if showUpdateModal && updateInfo != null}
    <Modal
      open={true}
      triggerBase="btn preset-tonal"
      contentBase="card bg-surface-200-800 p-4 space-y-4 shadow-xl w-[500px]"
      backdropClasses="backdrop-blur-xs"
      backdropBase="backdrop-none"
      onOpenChange={(ev) => {
        if (!ev.open) {
          showUpdateModal = false;
        }
      }}
    >
      {#snippet content()}
        <header class="flex justify-between">
          <h4 class="h4">更新提示</h4>
          <button
            type="button"
            class="btn preset-ghost-primary-500"
            onclick={() => (showUpdateModal = false)}
          >
            <X />
          </button>
        </header>

        <p>新版本:{updateInfo?.version}</p>
        <p>当前版本:{updateInfo?.currentVersion}</p>
        <p>更新内容</p>
        <pre>{updateInfo?.body}</pre>

        <footer class="flex justify-end gap-4">
          <button
            type="button"
            class="btn preset-tonal"
            onclick={() => (showUpdateModal = false)}>取消</button
          >
          <button
            type="button"
            class="btn preset-filled-primary-900-100"
            onclick={() => runUpdate()}
          >
            更新
          </button>
        </footer>
      {/snippet}
    </Modal>
  {/if}
  {#if showCloseModal}
    <Modal
      open={true}
      triggerBase="btn preset-tonal"
      contentBase="card bg-surface-200-800 p-4 space-y-4 shadow-xl w-[260px]"
      backdropClasses="backdrop-blur-xs"
      backdropBase="backdrop-none"
      onOpenChange={(ev) => {
        if (!ev.open) {
          showCloseModal = false;
        }
      }}
    >
      {#snippet content()}
        <header class="flex justify-between">
          <h4 class="h4">隐藏/关闭应用</h4>
          <button
            type="button"
            class="btn preset-ghost-primary-500"
            onclick={() => (showCloseModal = false)}
          >
            <X />
          </button>
        </header>

        <footer class="flex justify-end gap-4">
          <button
            type="button"
            class="btn preset-filled-primary-100-900"
            onclick={() => {
              showCloseModal = false;
              getCurrentWindow().hide();
            }}
          >
            隐藏窗口
          </button>
          <button
            type="button"
            class="btn bg-error-300-700 text-error-700-300"
            onclick={() => exit(0)}
          >
            关闭应用
          </button>
        </footer>
      {/snippet}
    </Modal>
  {/if}
</div>
